"""
视图及逻辑处理工具

"""
import hashlib
import random
from itertools import product

from flask import jsonify, g

# from ..models.common import NoRule
# from ..models.order import *
# from ..models.sdn import *
# from ..models.user import UserLog
# from ..models.work_order import *

# 1开头的一般为用户模块
code_map = {
    10000: '成功',
    10001: "短信发送失败",
    10002: "请勿重复发送验证码",
    10003: "验证码过期",
    10004: "密码错误",
    100015: "原密码错误",
    10005: "系统错误",
    10006: "没有权限",
    10007: "token过期请重新登录",
    10008: "记录未找到",
    10009: "参数不合法",
    10010: "Mqtt连接失败",
    10011: "未登录",
    10012: "文件未找到",
    10013: "超时",
    10014: "回调失败"
}


def resp_with_data(code=None, data=None, msg=None):
    if code != 10000:
        msg = code_map[code]
    if type(data) == dict and 'code' in data.keys() and data['code'] != 10000:
        response = jsonify({'code': data['code'], 'message': data["message"], 'data': data["data"]})
    elif type(msg) == dict:
        response = jsonify({'code': msg['code'], 'message': msg["message"], 'data': msg["data"]})
    else:
        response = jsonify({'code': code, 'message': msg, 'data': data})
    return response


def valid(*pairs):
    """

    参数校验
    :param pairs: (参数, 描述信息)的成对信息
    :return: 返回描述信息，用于抛出异常
    """
    for pair in pairs:
        if not pair[0] and pair[0] not in [True, False]:
            return pair[1]


def get_page(query):
    return {
        'page': g.page,
        'per_page': g.per_page,
        'total': query.count()
    }


def get_tree(model_name, id, vll_id=None):
    ids = list()
    obj = eval(model_name).get_or_none(eval(model_name).id == id)
    ids.append(str(id))
    if not vll_id:
        if obj.parent_id:
            res = get_tree(model_name, obj.parent_id)
            ids += res
    else:
        try:
            son_obj = eval(model_name).get_or_none(eval(model_name).parent_id == id,
                                                   eval(model_name).vll_relation__vll_id == vll_id,
                                                   eval(model_name).vll_relation__is_del == False, )
        except:
            son_obj = None
        if son_obj:
            res = get_tree(model_name, str(son_obj.id), vll_id)
            ids += res
    return ids


# def generate_no(model_name, date='', pre_num=-1, **kwargs):
#     '''
#     生成编号
#     :param model_name: 数据表model名称
#     :param date: 生成固定日期的编号 2022-10-10
#     :param pre_num: 之前编号的数据个数
#     :param kwargs:字段参数
#     :return:编号
#     '''
#     # 查找规则数据
#     try:
#         rule_obj = NoRule.get_or_none(NoRule.model_name ** ('%{}%'.format(model_name)))
#     except:
#         return ''
#     no = []
#     for_separate = False
#     if model_name in ['Vll', 'LogicPort']:
#         for_separate = True
#
#     condition = [eval(model_name).creation_time > 0] if for_separate else \
#         [eval(model_name).create_time > '1970-01-01']
#     # condition.append(eval(model_name).is_del == F)
#     # 是否需要做删除过滤？
#     # condition = {'is_del': 0}
#     for rule in rule_obj.rule.split('+'):
#         import time
#         if rule.startswith('%') and rule.endswith('%'):
#             rule = rule[1:-1].split(':')
#             if rule[0] == 'time':
#                 if date:
#                     rule = time.strftime(rule[1], time.strptime(date, '%Y-%m-%d'))
#                     today = time.strftime('%Y-%m-%d', time.strptime(date, '%Y-%m-%d'))
#                 else:
#                     rule = time.strftime(rule[1], time.localtime(time.time()))
#                     today = time.strftime('%Y-%m-%d', time.localtime(time.time()))
#                 condition.append(eval(model_name).creation_time > today) if for_separate else \
#                     condition.append(eval(model_name).create_time > today)
#             elif rule[0].startswith('field'):
#                 field = rule[0].split('-')[-1]
#                 if ',' in rule[1]:
#                     con_list = rule[1].split(',')
#                     for epr in con_list:
#                         # 支持 =
#                         if '=' in epr:
#                             con, val = epr.split('=')
#                             # 支持in 多个值用&隔开
#                             # d2d&c2c&d2c=B
#                             if '&' in con:
#                                 in_con = con.split('&')
#                                 if kwargs.get(field) in in_con:
#                                     condition.append(eval(model_name).field in in_con)
#                                     rule = val
#                             else:
#                                 if kwargs.get(field) == con:
#                                     if kwargs.get(field) != 'port':
#                                         condition.append(eval(model_name).type == kwargs.get(field))
#                                     rule = val
#                     # 最后一个结果为默认值
#                     if type(rule) == list:
#                         rule = ''
#                         condition.append(eval(model_name).field == kwargs.get(field))
#                 else:
#                     rule = rule[1]
#             elif rule[0] == 'auto':
#                 if pre_num == -1:
#                     if for_separate:
#                         pre_data = eval(model_name).select().where(*condition).order_by(
#                             eval(model_name).no.desc())
#                     else:
#                         pre_data = eval(model_name).select().where(*condition).order_by(
#                             eval(model_name).create_time.desc())
#                     if pre_data:
#                         try:
#                             pre_num = int(pre_data[0].no[-int(rule[1]):])
#                         except:
#                             pre_num = 0
#                     else:
#                         pre_num = 0
#                 rule = str(pre_num + 1).zfill(int(rule[1]))
#             else:
#                 rule = ''
#         no.append(rule)
#     return ''.join(no)


def create_verify_code(count=6, type='number'):
    if type == 'number':
        str_lib = '1234567890'
    else:
        str_lib = '1234567890abcdefghijklmnopqrstuvwxyz!@#$%^&*()'
    return ''.join(random.sample(str_lib, count))


def flatten_dict(data, parent_key='', sep='*'):
    flattened_dict = {}
    for key, value in data.items():
        new_key = f"{parent_key}{sep}{key}" if parent_key else key
        if isinstance(value, dict):
            # 递归处理嵌套字典
            flattened_dict.update(flatten_dict(value, new_key, sep=sep))
        else:
            flattened_dict[new_key] = value
    return flattened_dict


# def save_all_nos(model_name, date_list=None):
#     '''
#     重新保存编号方法
#     :param model_name: 数据表model名称
#     :param date_list: 列表 某天/某些天的编号重新排布 ["2022-08-16","2022-10-10]
#     :return:
#     '''
#     try:
#         rule_obj = NoRule.get_or_none(NoRule.model_name ** ('%{}%'.format(model_name)))
#     except:
#         return
#     # 判断编号是否携带时间
#     if "%time:" in rule_obj.rule:
#         with_date = True
#     else:
#         with_date = False
#     # 判断编号是否携带根据字段分别编号以及处理字段编号规则
#     field_con = ''
#     if "%field-" in rule_obj.rule:
#         with_field = True
#         for i in rule_obj.rule.split('+'):
#             if i.startswith('%field-'):
#                 field_con = i.replace('%', '')
#     else:
#         with_field = False
#     condition = {'create_time__gt': '1970-01-01'}
#     # 携带时间数据处理
#     if with_date:
#         if date_list:
#             condition['create_time__date__in'] = date_list
#         else:
#             query = (NoRule
#                      .select(fn.DATE(NoRule.create_time).alias('day'), fn.COUNT(NoRule.id).alias('count'))
#                      .group_by(fn.DATE(NoRule.create_time))
#                      .order_by(fn.DATE(NoRule.create_time)))
#             date_list = [row.day for row in query]
#
#     # 处理字段名称与编号在字段规则下的存储值
#     field = ''
#     con_list = []
#     field_val_list = []
#     if with_field and field_con:
#         field, con_list = field_con.split(':')
#         if ',' in con_list:
#             field = field.split('-')[-1]
#             con_list = con_list.split(',')
#             field_val_list = [i.split('=')[-1] for i in field_con.split(',')]
#     # 定义数量字典
#     n_dict_list = [[model_name]]
#     if with_date and date_list:
#         n_dict_list.append(date_list)
#     if field_val_list:
#         n_dict_list.append(field_val_list)
#     n_dict_list = list(product(*n_dict_list))
#     n_dict = {('_').join(i): 0 for i in n_dict_list}
#     # 查询数据
#     datas = eval(model_name).select().where(**condition).order_by('create_time')
#     if datas:
#         for data in datas:
#             data_date = ''
#             kwargs = {}
#             data_dict = model_to_dict(data)
#             key_list = [model_name]
#             # 如果携带日期 字典键拼接日期
#             if with_date:
#                 data_date = data.create_time.strftime('%Y-%m-%d')
#                 key_list.append(data_date)
#             # 如果携带根据字段编号规则，字典键拼接规则值，并传递字段参数
#             if with_field and field_con:
#                 for epr in con_list:
#                     if '=' in epr:
#                         con, val = epr.split('=')
#                         # 布尔类型转成 '0' / '1'
#                         if type(data_dict[field]) == bool:
#                             data_dict[field] = str(int(data_dict[field]))
#                         # 支持in 多个值用&隔开
#                         # d2d&c2c&d2c=B
#                         if '&' in con:
#                             in_con = con.split('&')
#                             if data_dict[field] in in_con:
#                                 key_list.append(str(val))
#                                 kwargs[field] = data_dict[field]
#                         # 支持 =
#                         else:
#                             if data_dict[field] == con:
#                                 key_list.append(str(val))
#                                 kwargs[field] = data_dict[field]
#             key = '_'.join(key_list)
#             no = generate_no(model_name, date=data_date, pre_num=n_dict[key], **kwargs)
#             n_dict[key] += 1
#             data.no = no
#             data.save()
#     return 'finish'
